import React, { Component, ComponentClass } from 'react';
import Taro from '@tarojs/taro';
import {AtAccordion, AtActionSheet, AtActionSheetItem, AtCheckbox, AtDrawer, AtIcon, AtLoadMore, AtRadio} from 'taro-ui'
import {connect} from 'react-redux'
import {Image, Input, Navigator, Text, View} from '@tarojs/components'
import {CategoryListPageGood, CityLocation, Good, ScreenItem} from '../../utils/server.interface'
import {platform} from '../../utils/platform-settting.service'
import {http} from '../../utils/http'
import {
  RESOURCE_URL,
  HOTEL_PRODUCT,
  HOTEL_OUT_PRODUCT,
  TARO_ENV,
  UPDATE_USER_SHARE_DATE,
  SCAN_BIND_SELLER,
  IDENTITY_IS_SELLER
} from '../../constants/api'
import Calendar from '../components/calendar/calendar-news'
import {DateType} from '../../reducers/select-date'
import {user} from '../../utils/user.service'
import SupportBar from '../../components/support-bar/support-bar'
import {vcmonitor} from "../../utils/tools";
import {h5Wx} from "../../utils/h5.service";
import GzhAuth from "../../components/gzh-auth/gzh-auth"
import Share from "../../components/share/share";
import './index.scss'
import './list.scss'

type PageStateProps = {
  selectDate: DateType
  location: CityLocation
}
type PageDispatchProps = {}

type PageOwnProps = {}

type PageState = {
  goods: Good[]
  loadMoreStatus: "more" | "loading" | "noMore"
  searchKey: string
  startDate: string
  endDate: string
  lng: string
  lat: string
  showCalendar: boolean
  screen: (ScreenItem & { data: { label: string; value: string }[] })[]
  accordionOpen: { [key: string]: any }
  sortFlag: boolean
  radioData: {
    price?: string
  }
  checkboxData: {
    [key: string]: string[]
  }
  drawerShow: boolean
  order: {
    price: 'DESC' | 'ASC'
    sale: 'DESC' | 'ASC'
  }
  diyPriceData: { max: string; min: string }
  isUser: boolean
  showMore: boolean
  linkUri: string
  order_by: string
}

type IProps = PageStateProps & PageDispatchProps & PageOwnProps

interface List {
  props: IProps
}

@connect(({selectDate, location}) => ({
  selectDate,
  location
}), (dispatch) => ({}))

class List extends Component {
  state: PageState = {
    goods: [],
    loadMoreStatus: 'loading',
    startDate: '',
    endDate: '',
    searchKey: '',
    lng: '',
    lat: '',
    showCalendar: false,
    screen: [],
    accordionOpen: {},
    radioData: {},
    checkboxData: {},
    sortFlag: false,
    drawerShow: false,
    isUser: true,
    order: {
      price: 'DESC',
      sale: 'DESC',
    },
    diyPriceData: {max: '', min: ''},
    showMore: true,
    order_by: '',
    linkUri: ''
  }

  async UNSAFE_componentWillMount() {
    const overseas = Taro.getCurrentInstance().router.params.overseas || ''
    const key = Taro.getCurrentInstance().router.params.key || ''
    const latitude = Taro.getCurrentInstance().router.params.latitude
    const longitude = Taro.getCurrentInstance().router.params.longitude
    const priceData = Taro.getCurrentInstance().router.params.priceData || '0'
    const star = Taro.getCurrentInstance().router.params.star || ''
    this.setState({searchKey: key, lng: longitude, lat: latitude}, async () => {
      const goods = await this.getData(this.page, overseas)
      let screen: ScreenItem[] = []
      const screenRet = await http.get<ScreenItem[]>('api/v3/market/hotel/getHotelLable', {})
      const accordionOpen: { [key: string]: any } = {}
      const checkboxData = {}
      const radioData = {}
      if (screenRet && screenRet.length > 0) {
        screen = screenRet.map(item => {
          accordionOpen[item.key] = false
          // 选择不限默认值
          if (item.key !== 'price') {
            checkboxData[item.key] = ['0']
          } else {
            radioData[item.key] = priceData
          }
          const data: { name: string; typeid: string; value?: string; label?: string }[] = [{
            name: '不限',
            typeid: '0',
            label: '不限',
            value: '0',
          }]
          item.data.map(i => {
            i['label'] = i.name
            i['value'] = `${i.typeid}`
            data.push(i)
          })
          item.data = data
          return item
        })
        if (star) {
          checkboxData['star'] = star.split(',')
        }
      }
      this.setState({
        showMore: goods.length <= 0,
        goods,
        screen,
        accordionOpen,
        checkboxData,
        radioData
      })
    })
  }

  shareParams = ''

  async componentDidShow() {
    vcmonitor(this)
    this.shareParams = await user.getSellerParams()
    let link = '/common/hotel/index?' + this.shareParams
    if (process.env.TARO_ENV === 'h5') {
      link = window.location.origin + link
      const shareData = {
        title: platform.info.platformName,
        desc: '酒店住宿',
        link,
        imgUrl: platform.info.platformLogo
      }
      h5Wx.share(shareData)
    } else {
      link += `&sKey=${Taro.getStorageSync('sKey' || '')}`
    }
    let isUser = true
    if (process.env.DISTINGUISH_IDENTITY) {
      const identityIsSeller = await http.get(IDENTITY_IS_SELLER, {})
      isUser = !identityIsSeller.isSeller
    }
    this.setState({linkUri: link, isUser})
    const bindSellerIds = Taro.getCurrentInstance().router.params.bindSellerId || ''
    const tempSellerIds = Taro.getCurrentInstance().router.params.tempSellerId || ''
    if ((bindSellerIds || tempSellerIds) && process.env.DISTINGUISH_IDENTITY) {
      http.HPost(SCAN_BIND_SELLER, { temp_seller_id: tempSellerIds, refer_seller_id: bindSellerIds });
    }
  }

  onShareAppMessage() {
    if (process.env.TARO_ENV !== 'tt') {
      http.post(UPDATE_USER_SHARE_DATE, {})
    }
    return {
      title: platform.info.platformName,
      path: '/common/hotel/index?' + this.shareParams + `&sKey=${Taro.getStorageSync('sKey' || '')}`
    }
  }

  page = 1

  async getData(page, overseas) {
    const searchData = Taro.getCurrentInstance().router.params;
    const outLocation = Taro.getStorageSync('outCity')
    const {checkboxData, radioData, diyPriceData, startDate, endDate} = this.state
    const data: { [key: string]: any } = {
      p: page,
      k: this.state.searchKey,
      lat: this.state.lat,
      lng: this.state.lng,
      c: searchData.category,
      areaId: this.props.location.region_id,
      startDate: startDate || this.props.selectDate.start,
      endDate: endDate || this.props.selectDate.end,
      days: this.props.selectDate.list.length + 1,
      price: searchData.price,
      star: searchData.star,
      order_by: this.state.order_by,
      destination_city: overseas == 1 ? outLocation.region_id : ''
    }
    Object.keys(radioData).map(item => {
      if (radioData[item] !== '0') {
        data[item] = radioData[item]
        if (item === 'price') {
          if (radioData[item] === '1') {
            data[item] = (diyPriceData.min || '0') + ',' + (diyPriceData.max || '1000000')
          } else {
            const categoryArr = this.state.screen.find(i => i.key === item) || {data: []}
            const priceNameArr: any[] = categoryArr.data || []
            data[item] = priceNameArr.find(i => i.typeid === radioData[item]).range || ''
          }
        }
      }
    })
    Object.keys(checkboxData).map(item => {
      if (!checkboxData[item].includes('0')) {
        data[item] = checkboxData[item].join(',')
      }
    })
    const goods = (await http.get<CategoryListPageGood[]>(overseas == 1 ? HOTEL_OUT_PRODUCT : HOTEL_PRODUCT, data)) || []
    if (goods.length === 10) {
      this.setState({loadMoreStatus: 'more'})
    } else {
      this.setState({loadMoreStatus: 'noMore'})
    }
    return goods
  }

  onReachBottom() {
    if (this.state.loadMoreStatus != 'noMore') {
      this.setState({loadMoreStatus: 'loading', showMore: true}, async () => {
        this.page++
        const goods = await this.getData(this.page)
        const old = this.state.goods
        this.setState({goods: [...old, ...goods]})
      })
    }
  }

  inputChange(e) {
    const value = e.detail.value
    if (!value) {
      this.search()
    }
    this.setState({searchKey: e.detail.value})
  }

  search() {

    this.setState({loadMoreStatus: 'loading', goods: [], showMore: true}, async () => {
      const overseas = Taro.getCurrentInstance().router.params.overseas || ''
      this.page = 1
      const goods = await this.getData(this.page, overseas)
      this.setState({goods, showMore: goods.length <= 0,})
    })
  }

  calendarSelect(value: { start: string; end: string; type: string; single: string; range: string[] }) {
    this.setState({
      showCalendar: false,
      startDate: value.start,
      endDate: value.end,
      durition: value.range.length + 1
    }, () => {
      this.search()
    })
  }

  showCalendar() {
    this.setState({showCalendar: true})
  }

  changeAccordion(type, value) {
    const state = this.state.accordionOpen
    state[type] = value
    this.setState({accordionOpen: state})
  }

  radioChange(type, value) {
    const radioData = this.state.radioData
    radioData[type] = String(value)
    if (type === 'price') {
      this.setState({radioData, diyPriceData: {max: '', min: ''}})
    } else {
      this.setState({radioData})
    }
  }

  priceInput(type, e) {
    const diyPriceData: { [key: string]: string } = this.state.diyPriceData
    let {min, max} = diyPriceData
    if (type === 'min') min = e.detail.value
    if (type === 'max') max = e.detail.value
    this.setState({diyPriceData: {min, max}})
    return e.detail.value
  }

  priceCheck() {
    let {min, max} = this.state.diyPriceData
    if (parseInt(min) >= parseInt(max)) {
      Taro.showToast({title: '最小金额应该小于最大金额', icon: 'none'})
      max = parseInt(min) + 1 + ''
      this.setState({diyPriceData: {min, max}})
    }
  }

  checkboxChange(type, value) {
    const checkboxData = this.state.checkboxData
    let data = checkboxData[type] || []

    if (data.includes(value)) {
      data = data.splice(data.findIndex(value), 1)
    } else {
      data = value
    }
    if (data[data.length - 1] === '0') {
      data = ['0']
    }
    if (data.length > 1 && data.includes('0')) {
      data = data.splice(data.findIndex(item => item === '0') - 1, 1)
    }
    checkboxData[type] = data.length === 0 ? ['0'] : data
    this.setState({checkboxData})
  }

  changeOrder(type) {
    const order = this.state.order
    if (type) {
      order[type] = order[type] === 'ASC' ? 'DESC' : 'ASC'
    }
    this.setState({order, goods: [], loadMoreStatus: 'loading', showMore: true}, async () => {
      this.page = 1
      const goods = await this.getData(this.page)
      this.setState({goods, showMore: goods.length <= 0,})
    })
  }

  screenConfirm() {
    this.setState({drawerShow: false, goods: [], loadMoreStatus: 'loading', showMore: true}, async () => {
      this.page = 1
      const goods = await this.getData(this.page)
      this.setState({goods, showMore: goods.length <= 0,})
    })
  }

  screenCancel() {
    const {radioData, checkboxData} = this.state
    Object.keys(radioData).map(item => {
      radioData[item] = '0'
    })
    Object.keys(checkboxData).map(item => {
      checkboxData[item] = ['0']
    })
    this.setState({radioData, checkboxData, diyPriceData: {min: '', max: ''}})
  }

  showDrawerItem(type) {
    const {accordionOpen} = this.state
    Object.keys(accordionOpen).map(item => {
      accordionOpen[item] = false
    })
    accordionOpen[type] = true
    this.setState({drawerShow: true}, () => {
      setTimeout(() => {
        this.setState({accordionOpen})
      }, 400)
    })
  }

  showSort(type) {
    this.setState({sortFlag: true})
  }

  hideSort(type) {
    this.setState({sortFlag: false})
  }

  choseSort(type) {
    this.setState({
      drawerShow: false,
      goods: [],
      loadMoreStatus: 'loading',
      showMore: true,
      order_by: type,
      sortFlag: false
    }, async () => {
      this.page = 1
      const goods = await this.getData(this.page)
      this.setState({goods, showMore: goods.length <= 0,})
    })
  }

  render() {
    const dataColor = Taro.getStorageSync('colorData');
    const {
      linkUri,
      isUser,
      showMore,
      loadMoreStatus,
      goods,
      showCalendar,
      screen,
      accordionOpen,
      radioData,
      checkboxData,
      drawerShow,
      diyPriceData
    } = this.state
    return (
      <View className='hotel-list-root'>
        <GzhAuth />
        {TARO_ENV === 'h5' && <View className='back' onClick={() => Taro.navigateBack()}>
          <AtIcon value='chevron-left' size='20' />
        </View>}
        <View className={TARO_ENV === 'h5' ? 'list-header-box-h5' : 'list-header-box'}>
          <View className='box'>
            <View className='date-box' onClick={this.showCalendar.bind(this)}>
              <View className='date-item'><Text
                className='tips'
              >住</Text><Text>{this.props.selectDate.start.split('-').slice(1, 3).join('.')}</Text></View>
              <View className='date-item'><Text
                className='tips'
              >离</Text><Text>{this.props.selectDate.end.split('-').slice(1, 3).join('.')}</Text></View>
            </View>
            <View className='input-box'>
              <Input className='input-item' type='text' value={this.state.searchKey} onConfirm={this.search.bind(this)}
                onInput={this.inputChange.bind(this)} placeholder='酒店·关键词'
              />
            </View>
            <View className='btn-box' onClick={this.search.bind(this)}>
              <View className='search'>查找</View>
            </View>
          </View>
        </View>
        <View className='screen-box'>
          <View className='left-box'>
            <View className='order-item' onClick={this.showDrawerItem.bind(this, 'price')}>
              <Text>价格</Text><Text className='xxhz xxhz-xiala-copy1' />
            </View>
            <View className='order-item' onClick={this.showDrawerItem.bind(this, 'star')}>
              <Text>星级</Text><Text className='xxhz xxhz-xiala-copy1' />
            </View>
            <View style='border-right:  solid 1Px #efefef;' className='order-item'
              onClick={this.showSort.bind(this, 'sort')}
            >
              <Text>排序</Text><Text className='xxhz xxhz-xiala-copy1' />
            </View>
            <View style='border-right:  solid 1Px #efefef;' className='order-item'
              onClick={this.showDrawerItem.bind(this, 'brand')}
            >
              <Text>品牌</Text><Text className='xxhz xxhz-xiala-copy1' />
            </View>
          </View>
          <View className='right-box'>
            <View className='btn' hoverClass='btn-hover' onClick={() => {
              this.setState({accordionOpen, drawerShow: true})
            }}
            >筛选<Text className='xxhz xxhz-xiala-copy1' /></View>
          </View>
        </View>
        <View className='other'>
          {goods.length > 0 && <View className='goods-box'>
            <View className='big-goods-box'>
              {goods.map(item => <Navigator key={item.id} className='good-item' url={item.url} hoverClass='none'>
                <View className='img-box'>
                  <Image lazyLoad src={item.img} mode='aspectFill' className='img' />
                  <View
                    className='tips'
                  >{item.cityName || ''}{item.category_name ? `·${item.category_name}` : ''}</View>
                </View>
                <View className='right'>
                  <View className='top'>
                    <View className='title'>{item.name}</View>
                    {item.serviceLabels && item.serviceLabels.length > 0 && <View className='labels'>
                      {item.serviceLabels && item.serviceLabels.length > 0 && item.serviceLabels.map((v, i) => <Text
                        key={i} className='label'
                      >{v.name}</Text>)}
                    </View>}
                  </View>
                  <View className='middle'>
                    <View className='middle-tag'>{
                      item.star == '10040001' ? '经济型' : item.star == '10040002' ? '舒适型' : item.star == '10040003' ? '高档型' : item.star == '10040004' ? '豪华型' : ''
                    }</View>
                    <View style='margin-left: 5px;line-height: 18px;'>
                      {item.star == '10040001' && (
                        <View><AtIcon value='sketch' size='16' color='#f2b04a' /><AtIcon value='sketch' size='16'
                          color='#f2b04a'
                        />
                        </View>
                      )
                      }
                      {item.star == '10040002' && (
                        <View><AtIcon value='sketch' size='16' color='#f2b04a' /><AtIcon value='sketch' size='16'
                          color='#f2b04a'
                        /><AtIcon
                          value='sketch' size='16' color='#f2b04a'
                        /> </View>
                      )
                      }
                      {item.star == '10040003' && (
                        <View><AtIcon value='sketch' size='16' color='#f2b04a' /><AtIcon value='sketch' size='16'
                          color='#f2b04a'
                        /><AtIcon
                          value='sketch' size='16' color='#f2b04a'
                        /><AtIcon value='sketch' size='16'
                          color='#f2b04a'
                        /> </View>
                      )
                      }
                      {item.star == '10040004' && (
                        <View><AtIcon value='sketch' size='16' color='#f2b04a' /><AtIcon value='sketch' size='16'
                          color='#f2b04a'
                        /><AtIcon
                          value='sketch' size='16' color='#f2b04a'
                        /><AtIcon value='sketch' size='16'
                          color='#f2b04a'
                        /><AtIcon
                          value='sketch' size='16' color='#f2b04a'
                        /> </View>
                      )
                      }
                    </View>
                  </View>
                  {!!item.salesVolume && !!platform.info.is_show_sales_volume &&
                  <View className='count'>销量{item.salesVolume}笔</View>}
                  <View className='price-box'>
                    {!!item.price ? <View className='price'><Text className='symbol'
                      style={`color: ${dataColor.priceColor}`}
                    >¥</Text><Text
                      className='number' style={`color: ${dataColor.priceColor}`}
                    >{item.price}</Text><Text>起</Text></View>
                    : <View className='snapped-up-look'>去看看</View>}
                  </View>
                </View>
              </Navigator>)}
            </View>
          </View>}
          {goods.length <= 0 && <View className='listNull'>
            <Image src={`${RESOURCE_URL}/resources/images/shopnull.png`} mode='widthFix' />
            <View className='text'>什么都没有,去看看别的吧~</View>
          </View>}
        </View>
        {showMore &&
        <AtLoadMore status={loadMoreStatus} noMoreText='' moreBtnStyle='border:none;' moreText='加载更多' />}
        <SupportBar />
        {showCalendar && <Calendar continuousType={2} type='range' onClose={() => {
          this.setState({showCalendar: false})
        }} onConfirm={this.calendarSelect.bind(this)}
        />}
        <AtDrawer onClose={() => {
          this.setState({drawerShow: false})
        }} show={drawerShow} mask right width='65%' className='drawer'
        >
          <View className='title'>筛选</View>
          <View className='content'>
            <View className='select-box'>
              {screen && screen.length > 0 && screen.map((item, index) => {
                return index === 5 ?
                  <View /> :
                  index != 5 ?
                    <AtAccordion key={item.key} onClick={this.changeAccordion.bind(this, item.key)}
                      title={item.title} open={accordionOpen[item.key]} hasBorder={false}
                    >
                      {item.key === 'price' && accordionOpen['price'] &&
                      <AtRadio options={item.data} value={radioData[item.key]}
                        onClick={this.radioChange.bind(this, item.key)}
                      />}
                      {item.key === 'price' && accordionOpen['price'] && <View className='price-diy'>
                        <Input onFocus={() => {
                          const radioData = this.state.radioData
                          radioData[item.key] = '1'
                          this.setState({radioData})
                        }} value={diyPriceData.min} onBlur={this.priceCheck.bind(this)}
                          onInput={this.priceInput.bind(this, 'min')} placeholderClass='input-place'
                          placeholder='最低价格' className='price-input' type='number'
                        />
                        -
                        <Input onFocus={() => {
                          const radioData = this.state.radioData
                          radioData[item.key] = '1'
                          this.setState({radioData})
                        }} value={diyPriceData.max} onBlur={this.priceCheck.bind(this)}
                          onInput={this.priceInput.bind(this, 'max')} placeholderClass='input-place'
                          placeholder='最高价格' className='price-input' type='number'
                        />
                      </View>}
                      {item.key !== 'price' && <AtCheckbox selectedList={checkboxData[item.key]} options={item.data}
                        onChange={this.checkboxChange.bind(this, item.key)}
                      >
                      </AtCheckbox>}
                    </AtAccordion> :
                    ''
              })}
            </View>
          </View>
          <View className='footer-btn'>
            <View className='btn reset' onClick={this.screenCancel.bind(this)}>重置</View>
            <View className='btn submit' onClick={this.screenConfirm.bind(this)}>确定</View>
          </View>
        </AtDrawer>
        <AtActionSheet isOpened={this.state.sortFlag} onClose={this.hideSort.bind(this, 'sort')}>
          {screen[5] && screen[5].data.length > 0 && screen[5].data.map((item, index) => {
              return index === 0 ?
                <View /> :
                index > 0 ?
                  <View onClick={this.choseSort.bind(this, item.typeid)} className={this.state.order_by == item.typeid ? 'order_by_chosed' : 'order_by_chose'}>
                    <View className='order_by_text'>
                      <AtActionSheetItem>
                        {item.name}
                      </AtActionSheetItem>
                      <View className={this.state.order_by == item.typeid ? 'order_by_logo' : 'order_by_logo_hide'}><AtIcon
                        className='chose-logo' value='check' size='20' color='#f1a43a'
                      /></View>
                    </View>
                  </View> :
                  ''
            }
          )
          }
        </AtActionSheet>
        {linkUri && <Share isUser={isUser} linkUri={linkUri} />}
      </View>
    )
  }
}

export default List as ComponentClass<PageOwnProps, PageState>
